import parkDao from "../dao/park";
import treeDao from "../dao/tree";
import {Cost, CostPie, CostRatio, Notice, Park} from "../types";
import {getCurrentTime, getUuid, logger} from "../utils";
import {codeFail, codeSuccess} from "../controller/resultData";
import manageService from "./manage";

export async function queryList() {
    try {
        return await parkDao.queryList();
    } catch (error) {
        logger(error);
    }
}

export async function insert(data:Park){
    try {
        const rank = await parkDao.getRank()
        return await parkDao.insert({ ...data, id: getUuid(),status:1,createTime:getCurrentTime(),rank});
    } catch (error) {
        logger(error);
    }
}

export async function deleteById(id){
    try {
        return await parkDao.deleteById(id);
    } catch (error) {
        logger(error);
    }
}

export async function update(data :Park){
    try {
        const park = await parkDao.queryById(data.id)
        if(park[0].status === 1 ){
            return codeSuccess(await parkDao.update({...data,endTime:getCurrentTime()}))
        }
        if(getDayDiff(new Date(park[0].endTime),new Date()) > 7 ){
            return codeFail('该项目已经结束超过7天，无法激活')
        }
        return codeSuccess(await parkDao.update({...data,endTime:getCurrentTime()}))
    } catch (error) {
        logger(error);
    }
}
export async function queryById(id){
    try {
        return await parkDao.queryById(id);
    } catch (error) {
        logger(error);
    }
}

export async function queryNotice() {
    try {
        const treeNoticeList = await getTreeNotice()
        const parkNoticeList = await getParkNotice()
        return [...treeNoticeList,...parkNoticeList];
    } catch (error) {
        logger(error);
    }
}

//获取当前时间与传入时间的时间差，精确到天
export function getDayDiff(startTime:Date,endTime:Date){
    const diff = endTime.getTime() - startTime.getTime();
    return Math.floor(diff / (24 * 3600 * 1000));
}

async function getTreeNotice(){
    try {
    const treeList = await treeDao.queryNotice()
    const noticeList:Notice[] = []
    if(treeList.length === 0){
        noticeList.push({
            type:0,
            title:'果树',
            content:'果树情况良好',
        })
    }else{
        noticeList.push({
            type:1,
            title:'果树',
            content:'有' + treeList.length + '颗树需要养护',
        })
    }
    return noticeList;
    } catch (error) {
        logger(error);
    }
}

async function getParkNotice(){
    try {
        const noticeList:Notice[] = []
        const parkList = await parkDao.queryListOnlyFinish()
        const r = filterByTypeAndRank(parkList)
        for (let i = 0; i < r.length; i++) {
            const park = r[i]
            const dayDiff = getDayDiff(new Date(park.endTime),new Date())
            if(dayDiff < 7){
                continue;
            }
            noticeList.push({
                type:0,
                title:park.name,
                content:'距离上次'+ park.name + '已经过去' + dayDiff + '天',
            })
        }
        return noticeList;
    }catch(error) {
        logger(error);
    }

}

function filterByTypeAndRank(arr:Park[]):Park[] {
    // 用于存储每个 type 对应的最大 rank 的对象
    const resultMap = {};

    // 遍历对象数组
    arr.forEach(item => {
        const { type, rank } = item;
        // 如果当前 type 还没有对应的对象，或者当前对象的 rank 更大
        if (!resultMap[type] || rank > resultMap[type].rank) {
            // 将当前对象存入 resultMap 中
            resultMap[type] = item;
        }
    });

    // 将 resultMap 中的值转换为数组并返回
    return Object.values(resultMap);
}

async function getCostBar(){
    const parkList = await parkDao.queryListOnlyFinish()
    const cost= calculateMonthlyCosts(parkList)
    const costBar:Cost = {
        title:'成本统计',
        total:calculateCost(parkList),
        data:cost,
    }
    return costBar;
}

function calculateCost(data) {
    let r = 0;
    for (let i = 0; i < data.length; i++) {
        const item = data[i];
        r += Number(item.price);
    }
    return r;
}
async function getCostPie(){
    const parkList = await parkDao.queryListOnlyFinish()
    const cost = await calculateCostByTypeWithTypeInfo(parkList)
    const costRatio:CostRatio = {
        title:'成本占比',
        data:cost as CostPie[],
    }
    return costRatio;
}

async function queryCost(){
    const costBar = await getCostBar()
    const costRatio = await getCostPie()
    return [costBar,costRatio];
}
async function getManage(id){
    return await manageService.queryById(id);
}

/**
 * 统计每个月的成本
 * @param data
 */
function calculateMonthlyCosts(data) {
    // 初始化一个长度为 12 的数组，用于存储每个月的成本，初始值都为 0
    const monthlyCosts = new Array(12).fill(0);

    // 遍历数组中的每个元素
    data.forEach(item => {
        // 获取 endTime 字段的值
        const endTime = item.endTime;
        // 获取 price 字段的值
        const price = Number(item.price);

        // 将 endTime 转换为 Date 对象
        const date = new Date(endTime);
        // 获取月份（注意：月份是从 0 开始的，所以 0 表示 1 月，11 表示 12 月）
        const month = date.getMonth();

        // 将该月的成本累加到对应的数组元素中
        monthlyCosts[month] += price;
    });

    return monthlyCosts;
}

/**
 * 统计每种类型的成本
 * @param data
 */
async function calculateCostByTypeWithTypeInfo(data) {
    const typeCostMap = {};
       for(const item of data){
           const { type, price } = item as any;
           const manage = await getManage(type);
           if (typeCostMap[type] === undefined) {
               typeCostMap[type] = { name: manage[0].name, value: Number(price),itemStyle:{
                       color: manage[0].color,
                   } };
           } else {
               typeCostMap[type].value += Number(price);
           }
       }
        // 将对象转换为数组
        return Object.values(typeCostMap);
}

/**
 * 统计每种类型每个月的成本
 * @param data
 */
async function calculateMonthlyCostByType(data) {
    // 用于存储每种类型每个月的成本
    const typeMonthlyCostMap = {};

    data.forEach(item => {
        const { endTime, type, price } = item;
        // 将 endtime 转换为 Date 对象
        const date = new Date(endTime);
        // 获取月份（注意：月份是从 0 开始的，所以 0 表示 1 月，11 表示 12 月）
        const month = date.getMonth();

        if (!typeMonthlyCostMap[type]) {
            // 如果该类型还没有记录，初始化一个长度为 12 的数组，用于存储每个月的成本
            typeMonthlyCostMap[type] = new Array(12).fill(0);
        }

        // 累加该类型该月的成本
        typeMonthlyCostMap[type][month] += Number(price);
    });

    // 将结果转换为所需的数组格式
    const result = [];
    for (const type in typeMonthlyCostMap) {
        const manage = await getManage(type)
        result.push({
            id:manage[0].id,
            title: manage[0].name,
            data: typeMonthlyCostMap[type],
            type: "line",
            itemStyle:{
                color: manage[0].color,
            }
        });
    }

    return result;
}

async function queryChart(){
    const parkList = await parkDao.queryListOnlyFinish()
    return await calculateMonthlyCostByType(parkList)
}
export default {
    queryList,
    insert,
    deleteById,
    update,
    queryById,
    queryNotice,
    queryCost,
    queryChart
};
